package com.dplus.common.utils.util;


import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
import org.apache.http.conn.util.PublicSuffixMatcher;
import org.apache.http.conn.util.PublicSuffixMatcherLoader;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

/**
 *  通用处理http请求（此工具类为单例对象）
* @ClassName: HttpToolUtil 
* @Description: TODO （描述）
* @author 作者 jacking
* @date 2016年12月30日 上午10:25:57
 */
public class HttpToolUtil {
/*	private RequestConfig requestConfig = RequestConfig.custom()
            .setSocketTimeout(15000)
            .setConnectTimeout(15000)
            .setConnectionRequestTimeout(15000)
            .build();*/
	
	private static HttpToolUtil instance = null;
	private HttpToolUtil(){}
	public static HttpToolUtil getInstance(){
		if (instance == null) {
			instance = new HttpToolUtil();
		}
		return instance;
	}
	
	/**
	 * 发送 post请求
	 * @param httpUrl 地址
	 */
	public String sendHttpPost(String httpUrl) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost  
		return sendHttpPost(httpPost);
	}
	
	/**
	 * 发送 post请求
	 * @param httpUrl 地址
	 * @param params 参数(格式:key1=value1&key2=value2)
	 */
	public String sendHttpPost(String httpUrl, String params) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost  
		try {
			//设置参数
			StringEntity stringEntity = new StringEntity(params, "UTF-8");
			stringEntity.setContentType("application/x-www-form-urlencoded");
			httpPost.setEntity(stringEntity);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sendHttpPost(httpPost);
	}
	
	/**
	 * 发送 post请求
	 * @param httpUrl 地址
	 * @param maps 参数
	 */
	public String sendHttpPost(String httpUrl, Map<String, String> maps) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost  
		// 创建参数队列  
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		for (String key : maps.keySet()) {
			nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
		}
		try {
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sendHttpPost(httpPost);
	}
	
	
	/**
	 * 发送 post请求（带文件）
	 * @param httpUrl 地址
	 * @param maps 参数
	 * @param fileLists 附件
	 */
	public String sendHttpPost(String httpUrl, Map<String, String> maps, List<File> fileLists) {
		HttpPost httpPost = new HttpPost(httpUrl);// 创建httpPost  
		MultipartEntityBuilder meBuilder = MultipartEntityBuilder.create();
		for (String key : maps.keySet()) {
			meBuilder.addPart(key, new StringBody(maps.get(key), ContentType.TEXT_PLAIN));
		}
		for(File file : fileLists) {
			FileBody fileBody = new FileBody(file);
			meBuilder.addPart("files", fileBody);
		}
		HttpEntity reqEntity = meBuilder.build();
		httpPost.setEntity(reqEntity);
		return sendHttpPost(httpPost);
	}
	
	/**
	 * 发送Post请求
	 * @param httpPost
	 * @return
	 */
	private String sendHttpPost(HttpPost httpPost) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
//			httpPost.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpPost);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}

	/**
	 * 发送 get请求
	 * @param httpUrl
	 */
	public String sendHttpGet(String httpUrl) {
		HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
		return sendHttpGet(httpGet);
	}
	
	/**
	 * 发送 get请求Https
	 * @param httpUrl
	 */
	public String sendHttpsGet(String httpUrl) {
		HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
		return sendHttpsGet(httpGet);
	}
	
	/**
	 * 发送Get请求
	 * @param httpPost
	 * @return
	 */
	private String sendHttpGet(HttpGet httpGet) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			httpClient = HttpClients.createDefault();
//			httpGet.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
	
	/**
	 * 发送Get请求Https
	 * @param httpPost
	 * @return
	 */
	private String sendHttpsGet(HttpGet httpGet) {
		CloseableHttpClient httpClient = null;
		CloseableHttpResponse response = null;
		HttpEntity entity = null;
		String responseContent = null;
		try {
			// 创建默认的httpClient实例.
			PublicSuffixMatcher publicSuffixMatcher = PublicSuffixMatcherLoader.load(new URL(httpGet.getURI().toString()));
			DefaultHostnameVerifier hostnameVerifier = new DefaultHostnameVerifier(publicSuffixMatcher);
			httpClient = HttpClients.custom().setSSLHostnameVerifier(hostnameVerifier).build();
//			httpGet.setConfig(requestConfig);
			// 执行请求
			response = httpClient.execute(httpGet);
			entity = response.getEntity();
			responseContent = EntityUtils.toString(entity, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (response != null) {
					response.close();
				}
				if (httpClient != null) {
					httpClient.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return responseContent;
	}
	
	/**
	 * 通用发送自定义http请求，支持rest
	 * @Description:  
	 * @param httpUrl   请求url
	 * @param httpType  四种get,post,put,delete
	 * @param maps      参数map, k,v
	 * @param isExistFile 是否有文件
	 * @param fileLists   文件集合
	 * @return
	 */
	public String sendHttpCustom(String httpUrl,String httpType, Map<String, String> maps,boolean isExistFile, List<File> fileLists) {
		CloseableHttpClient client = HttpClients.createDefault();
		CloseableHttpResponse resp = null;
		HttpEntity entity = null;
		String responseContent = null;
		httpType=httpType.toLowerCase();
		String param="?";
		int statusCode=500;
		// 创建参数队列  
		List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
		for (String key : maps.keySet()) {
			nameValuePairs.add(new BasicNameValuePair(key, maps.get(key)));
		}
		try {
			switch (httpType) {
			case "get":
				//遍历参数
				 for(Entry<String, String> entry:maps.entrySet()){
					 String key=entry.getKey();
					 String value=entry.getValue();
					 param+=key+"="+value+"&";
				 }
				 param=param.substring(0,param.length()-1);
				 httpUrl+=param;
				HttpGet get = new HttpGet(httpUrl);
				// 执行请求
//				get.setConfig(requestConfig);
				resp = client.execute(get);
				 statusCode = resp.getStatusLine().getStatusCode();
				if(statusCode>=200&&statusCode<300) {
					entity = resp.getEntity();
					responseContent = EntityUtils.toString(entity, "UTF-8");
				}
				break;
			case "post":
				HttpPost post = new HttpPost(httpUrl);
				if(isExistFile){
					MultipartEntityBuilder meBuilder = MultipartEntityBuilder.create();
					for (String key : maps.keySet()) {
						meBuilder.addPart(key, new StringBody(maps.get(key), ContentType.TEXT_PLAIN));
					}
					for(File file : fileLists) {
						FileBody fileBody = new FileBody(file);
						meBuilder.addPart("file", fileBody);
					}
					HttpEntity reqEntity = meBuilder.build();
					post.setEntity(reqEntity);
				}else{
					post.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
				}
//				post.setConfig(requestConfig);
				// 执行请求
				resp = client.execute(post);
				statusCode = resp.getStatusLine().getStatusCode();
				if(statusCode>=200&&statusCode<300) {
					entity = resp.getEntity();
					responseContent = EntityUtils.toString(entity, "UTF-8");
				}
				break;
			case "put":
				HttpPut put = new HttpPut(httpUrl);
				put.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
//				put.setConfig(requestConfig);
				// 执行请求
				resp = client.execute(put);
				 statusCode = resp.getStatusLine().getStatusCode();
				if(statusCode>=200&&statusCode<300) {
					entity = resp.getEntity();
					responseContent = EntityUtils.toString(entity, "UTF-8");
				}
				break;
			case "delete":
				//遍历参数
				 for(Entry<String, String> entry:maps.entrySet()){
					 String key=entry.getKey();
					 String value=entry.getValue();
					 param+=key+"="+value+"&";
				 }
				 param=param.substring(0,param.length()-1);
				 httpUrl+=param;
				 HttpDelete delete = new HttpDelete(httpUrl);
//				delete.setConfig(requestConfig);
				// 执行请求
				resp = client.execute(delete);
				 statusCode = resp.getStatusLine().getStatusCode();
				if(statusCode>=200&&statusCode<300) {
					entity = resp.getEntity();
					responseContent = EntityUtils.toString(entity, "UTF-8");
				}
				break;
			default:
				httpType = "get";
				//遍历参数
				 for(Entry<String, String> entry:maps.entrySet()){
					 String key=entry.getKey();
					 String value=entry.getValue();
					 param+=key+"="+value+"&";
				 }
				 param=param.substring(0,param.length()-1);
				 httpUrl+=param;
				HttpGet httpGet = new HttpGet(httpUrl);
				// 执行请求
//				httpGet.setConfig(requestConfig);
				resp = client.execute(httpGet);
				 statusCode = resp.getStatusLine().getStatusCode();
				if(statusCode>=200&&statusCode<300) {
					entity = resp.getEntity();
					responseContent = EntityUtils.toString(entity, "UTF-8");
				}
				break;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				// 关闭连接,释放资源
				if (resp != null) {
					resp.close();
				}
				if (client != null) {
					client.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	 return responseContent;
		
	}
	
	/**
	 * 发送json字符
	 * @param url
	 * @param json
	 */
	public String sendHttpPostJson(String url,String json){
		CloseableHttpClient client = HttpClients.createDefault();
		HttpPost post = new HttpPost(url);
		post.addHeader("Content-Type","application/json");
		StringEntity entity = new StringEntity(json, 
				ContentType.create("application/json", "utf-8"));
		post.setEntity(entity);
		CloseableHttpResponse resp;
		String content="";
		try {
			resp = client.execute(post);
			int sc = resp.getStatusLine().getStatusCode();
			if(sc>=200&&sc<300) {
				content=EntityUtils.toString(resp.getEntity());
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return content;
	}
	
	public static void main(String[] args) {
		String url="https://location.services.mozilla.com/v1/geolocate?key=test";
		String json="{\"cellTowers\": [{"
				+ "\"radioType\": \"wcdma\","
				+ "\"mobileCountryCode\": 460,"
				+ "\"mobileNetworkCode\": 0,"
				+ "\"locationAreaCode\": 34860,"
				+ "\"cellId\": 62041}]}";
		url="https://ap1.unwiredlabs.com/v2/process.php";
		json="{\"token\": \"96ebaead4eabb2\",\"radio\": \"gsm\",\"mcc\":310,\"mnc\": 410,\"cells\": [{"
      +"\"cid\": 17811,\"lac\": 7033,\"signal\": -60,\"tA\": 13}, { \"cid\": 17812,\"lac\": 7033}, {"
       +"\"cid\": 18513,\"lac\": 7033}],"
       +"\"wifi\": [{ \"bssid\": \"00:17:c5:cd:ca:aa\",\"channel\": 11,\"frequency\": 2412,\"signal\": -51}, {"
        +"\"bssid\": \"d8:97:ba:c2:f0:5a\"}],\"address\": 1}";
		int count=0;
		for(int i=0;i<30;i++){
			count++;
			String centent=HttpToolUtil.getInstance().sendHttpPostJson(url, json);
			System.out.println(""+count+":"+centent);
		}
	}
	
}
	
	
